package com.autotest.sync.stf;

import java.io.File;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON;
import com.autotest.sync.utils.ADBHelper;
import com.autotest.sync.utils.TimeUtil;

/** 
 * stf手机界面监控
 * @author thomas.ning
 * @version 2017年1月19日 下午6:46:58
 */
public class Stf {
	// CPU架构的种类
	public static final String ABIS_ARM64_V8A = "arm64-v8a";
	public static final String ABIS_ARMEABI_V7A = "armeabi-v7a";
	public static final String ABIS_X86 = "x86";
	public static final String ABIS_X86_64 = "x86_64";
	private static final String MINITOUCH_PORT = "minitouch";
	public static final int MAX_PORT = 2100;
	public static final int MIN_PORT = 2000;
	private volatile static int INIT_PORT = MIN_PORT - 1;
	private String MINICAP_FILE = "";
	private String MINITOUCH_FILE = "";
	private MiniTouchUtil mMiniTouchUtil = null;
	private boolean mFlag = false; //stf是否已启动
	private DeviceInfo mDevice = null;
	
	public Stf(String serial){
		mDevice = JSON.parseObject(ADBHelper.getDeviceInfo(serial),DeviceInfo.class);
	}
	
	/**
	 * 启动前准备
	 */
	private void prepare(){
		if(!checkFile()){
			this.pushFile();
			TimeUtil.sleep(1000);
			chmodMini();
		}
	}
	
	public void start(){
		if(mDevice.serial != null ){
			prepare();
			startMiniTouch();
		}
	}
	
	/**
	 * 启动MiniTouch
	 * @param deviceSerial
	 * @return
	 */
	public void startMiniTouch(){
		if(mDevice.serial == null){
			return;
		}
		int touchPort = getMiniTouchPort();
		mMiniTouchUtil = new MiniTouchUtil(touchPort, mDevice);
		mMiniTouchUtil.start();
	}
	
	/**
	 * 获取minitouch可用端口
	 */
	public int getMiniTouchPort(){
		return getMiniPort(MINITOUCH_PORT);
	}
	/**
	 * 根据类型, 获取mini可用端口
	 * @param minitype
	 * @return
	 */
	private int getMiniPort(String minitype){
		String result = ADBHelper.getForwardList();
		for(String tmp : result.split("\n")){
			String[] device = tmp.split("\\s+");
			if(device[0].equalsIgnoreCase(mDevice.serial)
					&&device[2].equalsIgnoreCase("localabstract:" + minitype )){
				return Integer.parseInt(device[1].substring(4));
			}
		}
		return getNextPort();
	}
	
	/**
	 * 获取下一个有用端口
	 * @return
	 */
	public static synchronized int getNextPort(){
		INIT_PORT = INIT_PORT > MAX_PORT ? MIN_PORT : (INIT_PORT+1);
		while(ADBHelper.isCheckLocalPortUse(INIT_PORT)){
			INIT_PORT += 1;
		}
		return INIT_PORT;
	}
	
	/**
	 * stf是否正在运行
	 * @return
	 */
	public boolean isRunning(){
		return mFlag;
	}
	/**
	 * 关闭所有运行资源
	 */
	public void close(){
		mFlag = false;
		if(mMiniTouchUtil != null){
			mMiniTouchUtil.close();
		}
	}
	
	
	/**
	 * 修改文件权限
	 */
	private void chmodMini(){
		String chmod = String.format(Config.ADB_CHMOD_COMMAND, Config.REMOTE_PATH, "mini*");
		ADBHelper.exec(String.format("adb -s %s shell %s", mDevice.serial, chmod), 5);
	}
	
	/**
	 * 检查手机端是否存在此文件
	 * @return
	 */
	public boolean checkFile(){
		String cmd = String.format("adb -s %s shell cd %s;ls", mDevice.serial,Config.REMOTE_PATH);
		String result = ADBHelper.execAndReturn(cmd);
		if(StringUtils.isEmpty(result)){
			return false;
		}
		boolean bminitouch = result.contains("minitouch");
		boolean bminicap = result.contains("minicap");
		if(bminitouch && bminicap){
			return true;
		}
		return false;
	}
	
	/**
	 * 上传相关文件到手机
	 */
	public void pushFile(){
		String abi = mDevice.cpuAbi;
		if (Integer.valueOf(mDevice.sdk_version) < 16) {
			MINITOUCH_FILE = Config.MINITOUCH_NOPIE;
			MINICAP_FILE = Config.MINICAP_NOPIE;
		}else {
			MINITOUCH_FILE = Config.MINITOUCH_BIN;
			MINICAP_FILE = Config.MINICAP_BIN;
		}
		File minicapBinFile = new File(Config.getMinicapBin(), abi
				+ File.separator + MINICAP_FILE);
		File minitouchBinFile = new File(Config.getMiniTouchBin(), abi
				+ File.separator + MINITOUCH_FILE);
		File minicapSoFile = new File(Config.getMinicapSo(), "android-" + mDevice.sdk_version
				+ File.separator + abi + File.separator + Config.MINICAP_SO);
		String minicapBinCmd = String.format(Config.ADB_PUSH_COMMAND, mDevice.serial, minicapBinFile, Config.REMOTE_PATH);
		String minitouchBinCmd= String.format(Config.ADB_PUSH_COMMAND, mDevice.serial, minitouchBinFile, Config.REMOTE_PATH);
		String minicapSoCmd= String.format(Config.ADB_PUSH_COMMAND, mDevice.serial, minicapSoFile, Config.REMOTE_PATH);
		ADBHelper.exec(minicapBinCmd, 10);
		ADBHelper.exec(minitouchBinCmd,10);
		ADBHelper.exec(minicapSoCmd, 10);
	}
	
	/**
	 * 获取miniTouch实例
	 */
	public MiniTouchUtil getMiniTouch(){
		return mMiniTouchUtil;
	}
}
